{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Fourier Neural Operator 2D"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\s1612415\\AppData\\Local\\Programs\\Python\\Python310\\lib\\site-packages\\tqdm\\auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "## Imports \n",
    "import matplotlib.pyplot as plt \n",
    "import numpy as np \n",
    "import torch \n",
    "import torch.nn as nn\n",
    "from timeit import default_timer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Set seeds\n",
    "torch.manual_seed(0)\n",
    "np.random.seed(0)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create Data"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Heat Equation:\n",
    "\n",
    "\\begin{align*}\n",
    "\\frac{\\partial u}{\\partial t} &= \\alpha \\frac{\\partial^2 u}{\\partial x^2} \\\\\n",
    "u(x, 0) &= x^2 \\\\\n",
    "u(0, t) &= u(1, t) = 2 - \\exp(-t)\n",
    "\\end{align*}\n",
    "\n",
    "Solution: \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "## TODO: Create Heat Equation Class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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2Ji8LpFISJLmzJmj48eP65prrsltdADN5Gc6Eonoc5/7nAoKCpLXXX/99RoeHta5c+dUWFiY0+Ygmsl5Xr9+vVatWqV7771XknTDDTfozJkz+s53vqNHHnlE+fn8/+tsSPdYWFJSkpNnRaTL+JmRwsJCLV26VD09PcnrEomEenp6VF9fP+Vt6uvrU46XpFdffTXt8ZjZeZakp59+Wo8//ri6u7t14403WqQGXqbn+rrrrtObb76p/v7+5OWrX/2qbr31VvX396uystIyPzBm8jO9bNkyvfvuu8mxJ0nvvPOOIpEIQySNmZznjz/+eNLgmBiAHv/MWtY4eSzM2UtjfWDfvn1eUVGRt2fPHm9gYMD7zne+41155ZXe8PCw53met2rVKu8HP/hB8vjf/OY33pw5c7xnnnnGO3bsmNfW1sZbe6ch0/O8adMmr7Cw0Pv5z3/uDQ0NJS9jY2OuvoXAyPRcX4h300xPpuf5gw8+8IqLi70HHnjAO378uPdv//ZvXllZmffEE0+4+hYCIdPz3NbW5hUXF3v/+q//6p04ccL71a9+5V1zzTXet771LVffQiCMjY15b7zxhvfGG294krwtW7Z4b7zxhvf+++97nud5P/jBD7xVq1Ylj594a+/3vvc979ixY97OnTt5a++l2r59u/fHf/zHXmFhoVdbW+v913/9V/K/3XLLLd7dd9+dcvzPfvYz79prr/UKCwu9L37xi94rr7xiXBxMmZznL3zhC56kSZe2tjb78ADK9Gf6/8cYmb5Mz/Prr7/u1dXVeUVFRd7ChQu9J5980jt//rxxdfBkcp4/+eQT77HHHvOuueYaLxQKeZWVld7999/v/d///Z99eID853/+55T/mztxbu+++27vlltumXSbxYsXe4WFhd7ChQu9f/qnf8ppY57n8dwWAABw57J9zQgAAAgGxggAAHCKMQIAAJxijAAAAKcYIwAAwCnGCAAAcIoxAgAAnGKMAAAApxgjAADAKcYIAABwijECAACcYowAAACn/h8Ypvc5LFIPQAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Steps in x direction\n",
    "nx = 10\n",
    "## Steps in t direction\n",
    "nt = 10\n",
    "\n",
    "h = 1 / nx ## Step size in x direction\n",
    "k = 1 / nt ## Step size in t direction\n",
    "\n",
    "alpha = 0.05\n",
    "r =  alpha * k / h**2\n",
    "\n",
    "X, T = np.meshgrid(np.linspace(0, 1, nx + 1), np.linspace(0, 1, nt + 1))\n",
    "\n",
    "plt.scatter(X, T)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Initial Condition\n",
    "beta = np.pi\n",
    "u0 = np.sin(beta * X[0]) \n",
    "\n",
    "## Boundary Conditions\n",
    "ux0 = 0 # u0[0] # T[:, 0]\n",
    "uxn = 0 # u0[-1] # 2 - np.exp(-T[:, -1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.zeros((nx - 1, nx - 1))\n",
    "B = np.zeros((nx - 1, nx - 1))\n",
    "\n",
    "for i in range(nx - 1):\n",
    "    A[i, i] = 2 + 2 * r\n",
    "    B[i, i] = 2 - 2 * r\n",
    "\n",
    "for i in range(nx - 2):\n",
    "    A[i + 1, i] = -r\n",
    "    A[i, i + 1] = -r\n",
    "    B[i + 1, i] = r\n",
    "    B[i, i + 1] = r\n",
    "\n",
    "Ainv = np.linalg.inv(A)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Compute Solution\n",
    "u = np.zeros((nt + 1, nx + 1))\n",
    "u[0] = u0\n",
    "u[:, 0] = ux0\n",
    "u[:, -1] = uxn\n",
    "\n",
    "# b = np.zeros(nx - 1)\n",
    "for j in range(1, nt + 1):\n",
    "    # b[0] = r * u[j - 1, 0] + r * u[j, 0]\n",
    "    # b[-1] = r * u[j - 1, -1] + r * u[j, -1]\n",
    "    u[j, 1:nx] = Ainv @ ((B @ u[j - 1, 1:nx])) # + b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.imshow(u, aspect='auto')\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Number of Samples \n",
    "n = 10000\n",
    "## Output\n",
    "data_in = []\n",
    "data_out = []\n",
    "\n",
    "## Generate Data\n",
    "for _ in range(n):\n",
    "    beta = np.random.uniform(-10, 10)\n",
    "    beta_mat = beta * np.ones((nt + 1, nx + 1))\n",
    "\n",
    "    u0 = np.sin(beta * X[0])\n",
    "\n",
    "    data_in.append([beta_mat, X, T])\n",
    "\n",
    "    ## Create Solution Matrix\n",
    "    u = np.zeros((nt + 1, nx + 1))\n",
    "    u[0] = u0\n",
    "    u[:, 0] = ux0\n",
    "    u[:, -1] = uxn\n",
    "\n",
    "    # b = np.zeros(nx - 1)\n",
    "    for j in range(1, nt + 1):\n",
    "        # b[0] = r * u[j - 1, 0] + r * u[j, 0]\n",
    "        # b[-1] = r * u[j - 1, -1] + r * u[j, -1]\n",
    "        u[j, 1:nx] = Ainv @ ((B @ u[j - 1, 1:nx])) # + b)\n",
    "\n",
    "    data_out.append(u)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\s1612415\\AppData\\Local\\Temp\\ipykernel_11188\\974941267.py:1: UserWarning: Creating a tensor from a list of numpy.ndarrays is extremely slow. Please consider converting the list to a single numpy.ndarray with numpy.array() before converting to a tensor. (Triggered internally at ..\\torch\\csrc\\utils\\tensor_new.cpp:233.)\n",
      "  data_in = np.array(torch.tensor(data_in).float())\n"
     ]
    }
   ],
   "source": [
    "data_in = np.array(torch.tensor(data_in).float())\n",
    "data_out = np.array(torch.tensor(data_out).float().unsqueeze(1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Data Loader\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "import pandas as pd\n",
    "\n",
    "class CustomDataset(Dataset):\n",
    "    def __init__(self, t, x):\n",
    "        self.t = t\n",
    "        self.x = x\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.t)\n",
    "    \n",
    "    def __getitem__(self, index):\n",
    "        return self.t[index], self.x[index]\n",
    "\n",
    "data = CustomDataset(data_in, data_out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701],\n",
       "        [0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701, 0.9762701, 0.9762701, 0.9762701, 0.9762701,\n",
       "         0.9762701]],\n",
       "\n",
       "       [[0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ],\n",
       "        [0.       , 0.1      , 0.2      , 0.3      , 0.4      ,\n",
       "         0.5      , 0.6      , 0.7      , 0.8      , 0.9      ,\n",
       "         1.       ]],\n",
       "\n",
       "       [[0.       , 0.       , 0.       , 0.       , 0.       ,\n",
       "         0.       , 0.       , 0.       , 0.       , 0.       ,\n",
       "         0.       ],\n",
       "        [0.1      , 0.1      , 0.1      , 0.1      , 0.1      ,\n",
       "         0.1      , 0.1      , 0.1      , 0.1      , 0.1      ,\n",
       "         0.1      ],\n",
       "        [0.2      , 0.2      , 0.2      , 0.2      , 0.2      ,\n",
       "         0.2      , 0.2      , 0.2      , 0.2      , 0.2      ,\n",
       "         0.2      ],\n",
       "        [0.3      , 0.3      , 0.3      , 0.3      , 0.3      ,\n",
       "         0.3      , 0.3      , 0.3      , 0.3      , 0.3      ,\n",
       "         0.3      ],\n",
       "        [0.4      , 0.4      , 0.4      , 0.4      , 0.4      ,\n",
       "         0.4      , 0.4      , 0.4      , 0.4      , 0.4      ,\n",
       "         0.4      ],\n",
       "        [0.5      , 0.5      , 0.5      , 0.5      , 0.5      ,\n",
       "         0.5      , 0.5      , 0.5      , 0.5      , 0.5      ,\n",
       "         0.5      ],\n",
       "        [0.6      , 0.6      , 0.6      , 0.6      , 0.6      ,\n",
       "         0.6      , 0.6      , 0.6      , 0.6      , 0.6      ,\n",
       "         0.6      ],\n",
       "        [0.7      , 0.7      , 0.7      , 0.7      , 0.7      ,\n",
       "         0.7      , 0.7      , 0.7      , 0.7      , 0.7      ,\n",
       "         0.7      ],\n",
       "        [0.8      , 0.8      , 0.8      , 0.8      , 0.8      ,\n",
       "         0.8      , 0.8      , 0.8      , 0.8      , 0.8      ,\n",
       "         0.8      ],\n",
       "        [0.9      , 0.9      , 0.9      , 0.9      , 0.9      ,\n",
       "         0.9      , 0.9      , 0.9      , 0.9      , 0.9      ,\n",
       "         0.9      ],\n",
       "        [1.       , 1.       , 1.       , 1.       , 1.       ,\n",
       "         1.       , 1.       , 1.       , 1.       , 1.       ,\n",
       "         1.       ]]], dtype=float32)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 11, 11)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data[0][0].shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataloader = DataLoader(data, batch_size=16, shuffle=True)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Build Network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using cpu device.\n"
     ]
    }
   ],
   "source": [
    "## Get Device for Training\n",
    "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "print(f'Using {device} device.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Fourier Integral Kernel 2D\n",
    "class FourierIntegralKernel2D(nn.Module):\n",
    "    def __init__(self, in_channels: int, out_channels: int, modes1: int, modes2: int):\n",
    "        super(FourierIntegralKernel2D, self).__init__()\n",
    "        '''\n",
    "        '''\n",
    "        self.in_channels = in_channels\n",
    "        self.out_channels = out_channels \n",
    "        self.modes1 = modes1 \n",
    "        self.modes2 = modes2\n",
    "        ## Set (random) weights for the linear transform\n",
    "        weights1 = torch.rand(self.modes1, self.modes2, self.out_channels, self.in_channels, dtype=torch.cfloat) \n",
    "        self.weights1 = nn.Parameter(weights1 / (self.in_channels * self.out_channels)) ## Optional: Scale weights\n",
    "        weights2 = torch.rand(self.modes1, self.modes2, self.out_channels, self.in_channels, dtype=torch.cfloat) \n",
    "        self.weights2 = nn.Parameter(weights2 / (self.in_channels * self.out_channels))\n",
    "\n",
    "    def forward(self, v: torch.Tensor) -> torch.Tensor:\n",
    "        '''\n",
    "        FFT -> Linear Transform -> Inverse FFT\n",
    "        '''\n",
    "        ## FFT\n",
    "        # print(f'v: {v.shape}')\n",
    "        v_rfft = torch.fft.rfft2(v)\n",
    "        # print(f'v_rfft: {v_rfft.shape}')\n",
    "\n",
    "        ## Linear Transform \n",
    "        lv_rfft = torch.zeros(v_rfft.shape, dtype=torch.cfloat)\n",
    "        # lv_rfft[:, :, :self.modes] = torch.einsum('koi, bki -> bko', self.weights, v_rfft[:, :, :self.modes].permute(0, 2, 1)).permute(0, 2, 1) ## TODO: Should I have 5 dimensions here?\n",
    "        lv_rfft[:, :, :self.modes1, :self.modes2] = torch.einsum('kloi, bkli -> bklo', self.weights1, v_rfft[:, :, :self.modes1, :self.modes2].permute(0, 2, 3, 1)).permute(0, 3, 1, 2)\n",
    "        # print(f'lv_rfft: {lv_rfft[0][0][:10, :10].shape}')\n",
    "        # print(f'lv_rfft: {lv_rfft[0][0][:10, :10]}')    \n",
    "        lv_rfft[:, :, -self.modes1:, :self.modes2] = torch.einsum('kloi, bkli -> bklo', self.weights2, v_rfft[:, :, -self.modes1:, :self.modes2].permute(0, 2, 3, 1)).permute(0, 3, 1, 2)\n",
    "\n",
    "        ## Inverse FFT\n",
    "        v2 = torch.fft.irfft2(lv_rfft, s=(v.shape[-2], v.shape[-1]))\n",
    "        # print(f'v2: {v2.shape}')\n",
    "        return v2\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Fourier Network Operator 2D\n",
    "class FourierNetworkOperator2D(nn.Module):\n",
    "    def __init__(self, da: int, du: int, width: int, modes1: int, modes2: int):\n",
    "        super(FourierNetworkOperator2D, self).__init__()\n",
    "        '''\n",
    "        '''\n",
    "        self.width = width\n",
    "        self.modes1 = modes1\n",
    "        self.modes2 = modes2\n",
    "\n",
    "        ## P: Lifts the lower dimensional function to higher dimensional space\n",
    "        self.P = nn.Conv2d(da, self.width, 1) ## TODO: Change da\n",
    "\n",
    "        ## K: Fourier integral kernel operator\n",
    "        self.k0 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        self.k1 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        self.k2 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        self.k3 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        # self.k4 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        # self.k5 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        # self.k6 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        # self.k7 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        # self.k8 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "        # self.k9 = FourierIntegralKernel2D(self.width, self.width, self.modes1, self.modes2)\n",
    "\n",
    "        ## W: Pointwise linear operator\n",
    "        self.w0 = nn.Conv2d(self.width, self.width, 1)\n",
    "        self.w1 = nn.Conv2d(self.width, self.width, 1)\n",
    "        self.w2 = nn.Conv2d(self.width, self.width, 1)\n",
    "        self.w3 = nn.Conv2d(self.width, self.width, 1)\n",
    "        # self.w4 = nn.Conv2d(self.width, self.width, 1)\n",
    "        # self.w5 = nn.Conv2d(self.width, self.width, 1)\n",
    "        # self.w6 = nn.Conv2d(self.width, self.width, 1)\n",
    "        # self.w7 = nn.Conv2d(self.width, self.width, 1)\n",
    "        # self.w8 = nn.Conv2d(self.width, self.width, 1)\n",
    "        # self.w9 = nn.Conv2d(self.width, self.width, 1)\n",
    "\n",
    "        ## Q: Projects the higher dimensional function to lower dimensional space\n",
    "        self.Q = nn.Conv2d(self.width, du, 1) ## TODO: Change du\n",
    "\n",
    "    def forward(self, x: torch.Tensor) -> torch.Tensor:\n",
    "        '''\n",
    "        '''\n",
    "        ## P\n",
    "        x = self.P(x)\n",
    "\n",
    "        ## Fourier Layer #0\n",
    "        ## K\n",
    "        x1 = self.k0(x)\n",
    "        ## W\n",
    "        x2 = self.w0(x)\n",
    "        ## Sum\n",
    "        x = x1 + x2\n",
    "        ## Gelu\n",
    "        x = nn.functional.gelu(x)\n",
    "        # x = nn.functional.gelu(x1)\n",
    "        # x = nn.functional.gelu(x2)\n",
    "\n",
    "        ## Fourier Layer #1\n",
    "        ## K\n",
    "        x1 = self.k1(x)\n",
    "        ## W\n",
    "        x2 = self.w1(x)\n",
    "        ## Sum \n",
    "        x = x1 + x2\n",
    "        ## Gelu\n",
    "        x = nn.functional.gelu(x)\n",
    "        # x = nn.functional.gelu(x1)\n",
    "        # x = nn.functional.gelu(x2)\n",
    "\n",
    "        ## Fourier Layer #2\n",
    "        ## K\n",
    "        x1 = self.k2(x)\n",
    "        ## W\n",
    "        x2 = self.w2(x)\n",
    "        ## Sum\n",
    "        x = x1 + x2\n",
    "        ## Gelu\n",
    "        x = nn.functional.gelu(x)\n",
    "        # x = nn.functional.gelu(x1)\n",
    "        # x = nn.functional.gelu(x2)\n",
    "\n",
    "        ## Fourier Layer #3\n",
    "        ## K\n",
    "        x1 = self.k3(x)\n",
    "        ## W\n",
    "        x2 = self.w3(x)\n",
    "        ## Sum\n",
    "        x = x1 + x2\n",
    "        ## Gelu\n",
    "        x = nn.functional.gelu(x)\n",
    "        # x = nn.functional.gelu(x1)\n",
    "        # x = nn.functional.gelu(x2)\n",
    "\n",
    "        # ## Fourier Layer #4\n",
    "        # ## K\n",
    "        # x1 = self.k4(x)\n",
    "        # ## W\n",
    "        # x2 = self.w4(x)\n",
    "        # ## Sum\n",
    "        # x = x1 + x2\n",
    "        # ## Gelu\n",
    "        # x = nn.functional.gelu(x)\n",
    "        # # x = nn.functional.gelu(x1)\n",
    "        # # x = nn.functional.gelu(x2)\n",
    "\n",
    "        # ## Fourier Layer #5\n",
    "        # ## K\n",
    "        # x1 = self.k5(x)\n",
    "        # ## W\n",
    "        # x2 = self.w5(x)\n",
    "        # ## Sum\n",
    "        # x = x1 + x2\n",
    "        # ## Gelu\n",
    "        # x = nn.functional.gelu(x)\n",
    "        # # x = nn.functional.gelu(x1)\n",
    "        # # x = nn.functional.gelu(x2)\n",
    "\n",
    "        # ## Fourier Layer #6\n",
    "        # ## K\n",
    "        # x1 = self.k6(x)\n",
    "        # ## W\n",
    "        # x2 = self.w6(x)\n",
    "        # ## Sum\n",
    "        # x = x1 + x2\n",
    "        # ## Gelu\n",
    "        # x = nn.functional.gelu(x)\n",
    "        # # x = nn.functional.gelu(x1)\n",
    "        # # x = nn.functional.gelu(x2)\n",
    "\n",
    "        # ## Fourier Layer #7\n",
    "        # ## K\n",
    "        # x1 = self.k7(x)\n",
    "        # ## W\n",
    "        # x2 = self.w7(x)\n",
    "        # ## Sum\n",
    "        # x = x1 + x2\n",
    "        # ## Gelu\n",
    "        # x = nn.functional.gelu(x)\n",
    "        # # x = nn.functional.gelu(x1)\n",
    "        # # x = nn.functional.gelu(x2)\n",
    "\n",
    "        # ## Fourier Layer #8\n",
    "        # ## K\n",
    "        # x1 = self.k8(x)\n",
    "        # ## W\n",
    "        # x2 = self.w8(x)\n",
    "        # ## Sum\n",
    "        # x = x1 + x2\n",
    "        # ## Gelu\n",
    "        # x = nn.functional.gelu(x)\n",
    "        # # x = nn.functional.gelu(x1)\n",
    "        # # x = nn.functional.gelu(x2)\n",
    "\n",
    "        # ## Fourier Layer #9\n",
    "        # ## K\n",
    "        # x1 = self.k9(x)\n",
    "        # ## W\n",
    "        # x2 = self.w9(x)\n",
    "        # ## Sum\n",
    "        # x = x1 + x2\n",
    "        # ## Gelu\n",
    "        # x = nn.functional.gelu(x)\n",
    "        # # x = nn.functional.gelu(x1)\n",
    "        # # x = nn.functional.gelu(x2)\n",
    "\n",
    "        ## Q\n",
    "        x = self.Q(x)\n",
    "        return x\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import operator\n",
    "# from functools import reduce\n",
    "\n",
    "# def count_parameters(model):\n",
    "#     c = 0\n",
    "#     for p in list(model.parameters()):\n",
    "#         c += reduce(operator.mul, list(p.size() + (2, ) if p.is_complex() else p.size()))\n",
    "#     return c\n",
    "\n",
    "# model = FourierNetworkOperator2D(3, 1, width=64, modes1=4, modes2=4)\n",
    "# print(f'Number of parameters: {count_parameters(model)}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "P.weight: 192\n",
      "P.bias: 64\n",
      "k0.weights1: 65536\n",
      "k0.weights2: 65536\n",
      "k1.weights1: 65536\n",
      "k1.weights2: 65536\n",
      "k2.weights1: 65536\n",
      "k2.weights2: 65536\n",
      "k3.weights1: 65536\n",
      "k3.weights2: 65536\n",
      "w0.weight: 4096\n",
      "w0.bias: 64\n",
      "w1.weight: 4096\n",
      "w1.bias: 64\n",
      "w2.weight: 4096\n",
      "w2.bias: 64\n",
      "w3.weight: 4096\n",
      "w3.bias: 64\n",
      "Q.weight: 64\n",
      "Q.bias: 1\n",
      "Total Trainable Params: 541249\n"
     ]
    }
   ],
   "source": [
    "def count_parameters(model):\n",
    "    total_params = 0\n",
    "    for name, parameter in model.named_parameters():\n",
    "        if not parameter.requires_grad: continue\n",
    "        params = parameter.numel()\n",
    "        print(f'{name}: {params}')\n",
    "        total_params+=params\n",
    "    print(f\"Total Trainable Params: {total_params}\")\n",
    "    return total_params\n",
    "    \n",
    "model = FourierNetworkOperator2D(3, 1, width=64, modes1=4, modes2=4)\n",
    "num_parameters = count_parameters(model)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Model Parameters\n",
    "learning_rate = 1e-3\n",
    "epochs = 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Loss Function\n",
    "loss_function = nn.MSELoss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Optimizer \n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Test 0\n",
    "## Initial Condition\n",
    "betat0 = np.random.uniform(-10, 10)\n",
    "beta_matt0 = betat0 * torch.from_numpy(np.ones((nt + 1, nx + 1))).float().unsqueeze(0).unsqueeze(0)\n",
    "\n",
    "## Compute Solution\n",
    "ut0 = np.zeros((nt + 1, nx + 1))\n",
    "ut0[0] = np.sin(betat0 * X[0]) \n",
    "ut0[:, 0] = ux0\n",
    "ut0[:, -1] = uxn\n",
    "\n",
    "# b = np.zeros(nx - 1)\n",
    "for j in range(1, nt + 1):\n",
    "    # b[0] = r * u[j - 1, 0] + r * u[j, 0]\n",
    "    # b[-1] = r * u[j - 1, -1] + r * u[j, -1]\n",
    "    ut0[j, 1:nx] = Ainv @ ((B @ ut0[j - 1, 1:nx])) # + b)\n",
    "\n",
    "upredt0 = model(torch.cat((beta_matt0, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "# print(upredt0.shape)\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(ut0, aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(upredt0.detach()[0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Test 1\n",
    "## Initial Condition\n",
    "betat1 = np.random.uniform(-10, 10)\n",
    "beta_matt1 = betat1 * torch.from_numpy(np.ones((nt + 1, nx + 1))).float().unsqueeze(0).unsqueeze(0)\n",
    "\n",
    "## Compute Solution\n",
    "ut1 = np.zeros((nt + 1, nx + 1))\n",
    "ut1[0] = np.sin(betat1 * X[0]) \n",
    "ut1[:, 0] = ux0\n",
    "ut1[:, -1] = uxn\n",
    "\n",
    "# b = np.zeros(nx - 1)\n",
    "for j in range(1, nt + 1):\n",
    "    # b[0] = r * u[j - 1, 0] + r * u[j, 0]\n",
    "    # b[-1] = r * u[j - 1, -1] + r * u[j, -1]\n",
    "    ut1[j, 1:nx] = Ainv @ ((B @ ut1[j - 1, 1:nx])) # + b)\n",
    "\n",
    "upredt1 = model(torch.cat((beta_matt1, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(ut1, aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(upredt1.detach()[0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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y5Yt07hx41RcXKzJkyfr7bffPu743/72txo/fryKi4t14YUX6g9/+EM/zbR3dXV1uvzyy1VaWqpRo0Zp1qxZ2rVr13Gfs2rVKsVisW5LcXFxP824dz/72c+Omdf48eOP+5x8PCZHjBs37pj9icViqq2t7XF8Ph2XTZs26frrr1dlZaVisZjWrl3b7fEQghYvXqzRo0erpKRENTU12r179wnr9vWay0f0Df/z82hR6h30jWNZ9I28DiQvvviiFixYoCVLlmjHjh2aNGmSpk2bpgMHDvQ4/q233tK3vvUt3XLLLdq5c6dmzZqlWbNm6b333uvnmXf3+uuvq7a2Vlu2bNH69evV0dGha6+9Vi0tLcd93rBhw/Tpp592Lfv27eunGR/fhAkTus3rjTfe6HVsvh6TI955551u+7J+/XpJ0g033NDrc/LluLS0tGjSpElatmxZj48/8sgjevzxx7VixQpt3bpVQ4cO1bRp09TW1vuHz/X1mstH9I38OD97EpXeQd/ozqxvhDx2xRVXhNra2q6vM5lMqKysDHV1dT2O/+Y3vxlmzJjRbd3kyZPD7bffntN59tWBAweCpPD666/3OmblypWhrKys/yZ1kpYsWRImTZp00uMHyjE54q677grnnHNOyGazPT6er8dFUlizZk3X19lsNlRUVIRf/OIXXesOHjwYkslkeP7553ut09drLh/RN8r6b1J9EOXeQd+w6Rt5e4ekvb1d27dvV01NTde6eDyumpoabd68ucfnbN68udt4SZo2bVqv4700NjZKkkaMGHHccc3NzRo7dqyqqqo0c+ZMvf/++/0xvRPavXu3Kisr9YUvfEGzZ8/WRx991OvYgXJMpMPn3DPPPKObb775uB/Olq/H5b/t3btXDQ0N3V77srIyTZ48udfX/lSuuXxD38jv8zOKvYO+Ydc38jaQfPbZZ8pkMiovL++2vry8XA0NDT0+p6GhoU/jPWSzWc2fP19Tp07VxIkTex33xS9+UU8//bRefvllPfPMM8pms7ryyiv18ccf9+NsjzV58mStWrVK69at0/Lly7V371595StfUVNTU4/jB8IxOWLt2rU6ePCgvvvd7/Y6Jl+Py9GOvL59ee1P5ZrLN/SN/D0/o9o76Bt2fSPvPu036mpra/Xee+8d92enkjRlyhRNmTKl6+srr7xS559/vp588kndf//9uZ5mr6ZPn97174suukiTJ0/W2LFj9dJLL+mWW25xm5eFX//615o+fboqKyt7HZOvxwXRNtD7hhTd3kHfsJO3d0hGjhypRCKh/fv3d1u/f/9+VVRU9PicioqKPo3vb/PmzdMrr7yi1157rU8fky5JhYWFuvjii7Vnz54cze7UDB8+XOedd16v88r3Y3LEvn379Kc//Unf+973+vS8fD0uR17fvrz2p3LN5Rv6Rnf5en5K0egd9A3bvpG3gaSoqEiXXnqpNmzY0LUum81qw4YN3ZLmf5syZUq38ZK0fv36Xsf3lxCC5s2bpzVr1ujPf/6zqqur+1wjk8no3Xff1ejRo3Mww1PX3NysDz/8sNd55esxOdrKlSs1atQozZgxo0/Py9fjUl1drYqKim6vfSqV0tatW3t97U/lmss39I3u8vX8lKLRO+gbxn2jT78C289eeOGFkEwmw6pVq8Lf//73cNttt4Xhw4eHhoaGEEII3/nOd8I999zTNf7NN98MBQUF4dFHHw3/+Mc/wpIlS0JhYWF49913vXYhhBDCHXfcEcrKysLGjRvDp59+2rW0trZ2jTl6X+69997w6quvhg8//DBs37493HTTTaG4uDi8//77HrvQ5Uc/+lHYuHFj2Lt3b3jzzTdDTU1NGDlyZDhw4EAIYeAck/+WyWTCmDFjwt13333MY/l8XJqamsLOnTvDzp07g6Tw2GOPhZ07d4Z9+/aFEEJ46KGHwvDhw8PLL78c/va3v4WZM2eG6urqcOjQoa4aX//618MTTzzR9fWJrrmBgL6RH+fn0aLWO+gb9n0jrwNJCCE88cQTYcyYMaGoqChcccUVYcuWLV2Pfe1rXwtz5szpNv6ll14K5513XigqKgoTJkwIv//97/t5xseS1OOycuXKrjFH78v8+fO79ru8vDx84xvfCDt27Oj/yR/lxhtvDKNHjw5FRUXh85//fLjxxhvDnj17uh4fKMfkv7366qtBUti1a9cxj+XzcXnttdd6PK+OzDebzYZFixaF8vLykEwmwzXXXHPMPo4dOzYsWbKk27rjXXMDBX3D//w8WtR6B31jSbd1Fn0jFkIIfbunAgAAYCtvf4cEAAAMHgQSAADgjkACAADcEUgAAIA7AgkAAHBHIAEAAO4IJAAAwB2BBAAAuCOQAAAAdwQSAADgjkACAADcEUgAAIC7/wUAiZaxJa3oQgAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Test 2\n",
    "## Initial Condition\n",
    "betat2 = np.random.uniform(-10, 10)\n",
    "beta_matt2 = betat2 * torch.from_numpy(np.ones((nt + 1, nx + 1))).float().unsqueeze(0).unsqueeze(0)\n",
    "\n",
    "## Compute Solution\n",
    "ut2 = np.zeros((nt + 1, nx + 1))\n",
    "ut2[0] = np.sin(betat2 * X[0]) \n",
    "ut2[:, 0] = ux0\n",
    "ut2[:, -1] = uxn\n",
    "\n",
    "# b = np.zeros(nx - 1)\n",
    "for j in range(1, nt + 1):\n",
    "    # b[0] = r * u[j - 1, 0] + r * u[j, 0]\n",
    "    # b[-1] = r * u[j - 1, -1] + r * u[j, -1]\n",
    "    ut2[j, 1:nx] = Ainv @ ((B @ ut2[j - 1, 1:nx])) # + b)\n",
    "\n",
    "upredt2 = model(torch.cat((beta_matt2, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(ut2, aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(upredt2.detach()[0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Training Loop\n",
    "def train_loop(dataloader, model, loss_function, optimizer):\n",
    "    size = len(dataloader.dataset)\n",
    "    for batch, (t, x) in enumerate(dataloader):\n",
    "        # Compute prediction and loss\n",
    "        pred = model(t)\n",
    "        loss = loss_function(pred, x)\n",
    "\n",
    "        # Backpropagation\n",
    "        optimizer.zero_grad()\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "\n",
    "        if batch % 100 == 0:\n",
    "            loss, current = loss.item(), batch * len(t)\n",
    "            print(f\"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1\n",
      "-------------------------------\n",
      "loss: 0.137779  [    0/10000]\n",
      "loss: 0.001859  [ 1600/10000]\n",
      "loss: 0.000505  [ 3200/10000]\n",
      "loss: 0.000470  [ 4800/10000]\n",
      "loss: 0.000546  [ 6400/10000]\n",
      "loss: 0.000184  [ 8000/10000]\n",
      "loss: 0.000315  [ 9600/10000]\n",
      "Epoch 2\n",
      "-------------------------------\n",
      "loss: 0.000079  [    0/10000]\n",
      "loss: 0.000140  [ 1600/10000]\n",
      "loss: 0.003789  [ 3200/10000]\n",
      "loss: 0.000138  [ 4800/10000]\n",
      "loss: 0.000061  [ 6400/10000]\n",
      "loss: 0.000038  [ 8000/10000]\n",
      "loss: 0.000121  [ 9600/10000]\n",
      "Epoch 3\n",
      "-------------------------------\n",
      "loss: 0.000162  [    0/10000]\n",
      "loss: 0.000064  [ 1600/10000]\n",
      "loss: 0.000030  [ 3200/10000]\n",
      "loss: 0.000071  [ 4800/10000]\n",
      "loss: 0.000030  [ 6400/10000]\n",
      "loss: 0.000238  [ 8000/10000]\n",
      "loss: 0.000132  [ 9600/10000]\n",
      "Epoch 4\n",
      "-------------------------------\n",
      "loss: 0.000072  [    0/10000]\n",
      "loss: 0.000413  [ 1600/10000]\n",
      "loss: 0.000240  [ 3200/10000]\n",
      "loss: 0.000026  [ 4800/10000]\n",
      "loss: 0.000010  [ 6400/10000]\n",
      "loss: 0.000006  [ 8000/10000]\n",
      "loss: 0.000033  [ 9600/10000]\n",
      "Epoch 5\n",
      "-------------------------------\n",
      "loss: 0.000017  [    0/10000]\n",
      "loss: 0.000020  [ 1600/10000]\n",
      "loss: 0.000143  [ 3200/10000]\n",
      "loss: 0.000051  [ 4800/10000]\n",
      "loss: 0.000027  [ 6400/10000]\n",
      "loss: 0.000014  [ 8000/10000]\n",
      "loss: 0.000077  [ 9600/10000]\n",
      "Done!\n"
     ]
    }
   ],
   "source": [
    "for t in range(epochs):\n",
    "    print(f\"Epoch {t+1}\\n-------------------------------\")\n",
    "    train_loop(dataloader, model, loss_function, optimizer)\n",
    "print(\"Done!\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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4iMf+UhxySWXjG7/hz/8oZgyZUrxne98p/jb3/5WrFy5spg6dWrx6KOP5jqEoiiK4tOf/nTR1tZW3HPPPcUzzzwzennhhRdGt9n9WC677LLirrvuKp544oli3bp1xbnnnlu0tLQUf/nLX3IcwqgvfOELxT333FNs3ry5+MMf/lB0dXUVRx55ZLFt27aiKCbOOflv5XK5mDNnTvHlL395j9tq+bw8//zzxYYNG4oNGzYUEVFceeWVxYYNG4otW7YURVEU3/jGN4pDDz20uOOOO4o///nPxdlnn13MmzevePHFF0dnvPvd7y6uuuqq0a9f6jk3EciN2nh87q7eskNupM+Nmi4kRVEUV111VTFnzpyiubm5OPXUU4u1a9eO3vbOd76zOP/888dsf+uttxZveMMbiubm5uLYY48tfvnLXx7kFe8pIvZ6uf7660e32f1Yli1bNnrc7e3txfve975i/fr1B3/xuznnnHOK2bNnF83NzcVrXvOa4pxzzik2bdo0evtEOSf/7a677ioioti4ceMet9Xyefnd736318fVrvVWKpXi0ksvLdrb24tSqVS85z3v2eMY586dW6xcuXLMdft7zk0UciP/43N39ZYdcmPlmOtS5EZDURTF+F5TAQBIq2Z/hwQAmDwUEgAgO4UEAMhOIQEAslNIAIDsFBIAIDuFBADITiEBALJTSACA7BQSACA7hQQAyE4hAQCy+38GPm/6ydj2/QAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Test 0\n",
    "upredt0 = model(torch.cat((beta_matt0, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(ut0, aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(upredt0.detach()[0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Pg+kXrJDboyULDeKKnbaaacV3d3dw18PDQ0VHR0dRU9PzwG3//CHP1wsWLBgxHVz5swpPvvZz1Z0naO1ZcuWIiKK++6776Db3HDDDUVbW9vhW9QrtHTp0mL27NmvePtaOSd7feELXyje8IY3FOVy+YC3V+t5iYji9ttvH/66XC4XU6dOLb73ve8NX/f8888XpVKpuPnmmw86Z7TPuWokN9oO36JGoZ6zQ26kyY2qfYVk165dsWbNmujq6hq+rrGxMbq6umLlypUH/J6VK1eO2D4iYt68eQfdPpf+/v6IiDjqqKNecrtt27bFjBkzorOzM84555z461//ejiW97LWr18fHR0d8frXvz7OP//8ePrppw+6ba2ck4j/fsz9/Oc/j0984hMv+eFs1XpeXmzjxo3R19c34r5va2uLOXPmHPS+P5TnXLWRG9X9+KzH7JAb6XKjagvJc889F0NDQ9He3j7i+vb29ujr6zvg9/T19Y1q+xzK5XIsXrw4zjjjjDjxxBMPut2b3/zm+OlPfxp33nln/PznP49yuRynn356PPPMM4dxtfubM2dOLF++PO6666647rrrYuPGjfGud70rtm7desDta+Gc7HXHHXfE888/Hx//+McPuk21npd97b1/R3PfH8pzrtrIjep9fNZrdsiNdLlRdZ/2W++6u7vj8ccff8nfnUZEzJ07N+bOnTv89emnnx5vectb4oc//GFceeWVlV7mQc2fP3/43yeffHLMmTMnZsyYEbfddlt88pOfzLauFH7yk5/E/Pnzo6Oj46DbVOt5ob7Vem5E1G92yI10qvYVkmOOOSaamppi8+bNI67fvHlzTJ069YDfM3Xq1FFtf7gtWrQofv3rX8cf//jHUX1MekTE+PHj421ve1ts2LChQqs7NJMnT443velNB11XtZ+TvTZt2hS///3v41Of+tSovq9az8ve+3c09/2hPOeqjdwYqVofnxH1kR1yI21uVG0haW5ujne84x2xYsWK4evK5XKsWLFiRNN8sblz547YPiLinnvuOej2h0tRFLFo0aK4/fbb4w9/+EPMmjVr1DOGhobisccei2nTplVghYdu27Zt8dRTTx10XdV6TvZ1ww03xJQpU2LBggWj+r5qPS+zZs2KqVOnjrjvBwYGYvXq1Qe97w/lOVdt5MZI1fr4jKiP7JAbiXNjVH8Ce5jdcsstRalUKpYvX1787W9/Kz7zmc8UkydPLvr6+oqiKIqPfexjxaWXXjq8/YMPPliMGzeu+P73v1/8/e9/L5YuXVqMHz++eOyxx3IdQlEURXHRRRcVbW1txb333lv861//Gr7s2LFjeJt9j+WKK64o7r777uKpp54q1qxZU5x33nlFS0tL8de//jXHIQz70pe+VNx7773Fxo0biwcffLDo6uoqjjnmmGLLli1FUdTOOXmxoaGhYvr06cVXv/rV/W6r5vOydevWYt26dcW6deuKiCiuuuqqYt26dcWmTZuKoiiKb3/728XkyZOLO++8s/jLX/5SnHPOOcWsWbOKF154YXjG+973vuKaa64Z/vrlnnO1QG5Ux+NzX/WWHXIjfW5UdSEpiqK45ppriunTpxfNzc3FaaedVqxatWr4tve85z3FBRdcMGL72267rXjTm95UNDc3FyeccELxm9/85jCveH8RccDLDTfcMLzNvseyePHi4eNub28vPvjBDxZr1649/Ivfx7nnnltMmzataG5uLl73utcV5557brFhw4bh22vlnLzY3XffXURE8cQTT+x3WzWflz/+8Y8HfFztXW+5XC4uu+yyor29vSiVSsX73//+/Y5xxowZxdKlS0dc91LPuVohN/I/PvdVb9khN5aOuC5FbjQURVGM7jUVAIC0qvZvSACAsUMhAQCyU0gAgOwUEgAgO4UEAMhOIQEAslNIAIDsFBIAIDuFBADITiEBALJTSACA7BQSACC7/wcis2XwRoASTwAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Test 1\n",
    "upredt1 = model(torch.cat((beta_matt1, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(ut1, aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(upredt1.detach()[0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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311ceumlo9v/8pe/LJqamoqvfe1rxR/+8Idi5cqVxZQpU4rHHnss1yEURVEUH/rQh4r29vbi3nvvLf72t7+N3p599tnRbfY9liuuuKK46667iqeeeqpYt25dcf755xctLS3F7373uxyHMOoTn/hEce+99xabNm0qfvnLXxY9PT3FMcccU2zdurUoiolzTv7TyMhIMWfOnOLTn/70fo/V8nnZtm1bsWHDhmLDhg1FRBRXXXVVsWHDhmLz5s1FURTFl770peKII44o7rjjjuK3v/1tcc455xTd3d3Fv/71r9EZb37zm4urr7569OPne81NBHKjNp6f+6q37JAb6XOjpgtJURTF1VdfXcyZM6dobm4uTj/99OLBBx8cfey//uu/igsvvHDM9rfeemvxyle+smhubi5OPPHE4sc//vFhXvH+IuKAt+uvv350m32PZfny5aPH3dHRUbztbW8r1q9ff/gXv4/zzjuvmD17dtHc3Fy89KUvLc4777ziySefHH18opyT/3TXXXcVEVFs3Lhxv8dq+bzcc889B3xe7V1vpVIpLrvssqKjo6Mol8vFW97ylv2Oce7cucXKlSvH3Pdcr7mJQm7kf37uq96yQ26sHHNfitwoFUVRjO+aCgBAWjX7MyQAwOShkAAA2SkkAEB2CgkAkJ1CAgBkp5AAANkpJABAdgoJAJCdQgIAZKeQAADZKSQAQHYKCQCQ3f8DQjsPytJ74LoAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "## Test 2\n",
    "upredt2 = model(torch.cat((beta_matt2, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(ut2, aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(upredt2.detach()[0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Predict at Higher Resolution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### What does the Fourier Layer do?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch.utils.hooks.RemovableHandle at 0x23ef85fd660>"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "activation = {}\n",
    "def get_activation(name):\n",
    "    def hook(model, input, output):\n",
    "        activation[name] = output.detach()\n",
    "    return hook\n",
    "\n",
    "model.k0.register_forward_hook(get_activation('k0'))\n",
    "model.w0.register_forward_hook(get_activation('w0'))\n",
    "model.k1.register_forward_hook(get_activation('k1'))\n",
    "model.w1.register_forward_hook(get_activation('w1'))\n",
    "model.k2.register_forward_hook(get_activation('k2'))\n",
    "model.w2.register_forward_hook(get_activation('w2'))\n",
    "model.k3.register_forward_hook(get_activation('k3'))\n",
    "model.w3.register_forward_hook(get_activation('w3'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "upredt0 = model(torch.cat((beta_matt0, torch.from_numpy(X).float().unsqueeze(0).unsqueeze(0), torch.from_numpy(T).float().unsqueeze(0).unsqueeze(0)), 1))\n",
    "# print(activation['k0'].shape)\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.imshow(activation['k0'][0][0], aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(activation['w0'][0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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T9Z7773XG8s7rm3btqmyslJnnHGGpk6dqo8++qjbbfvKOZH+9Zx7+umnddNNNx3zw9my9bx80Y4dO9TY2NjpsY/H46qpqen2sT+Z11y2YW5k9/MzjLODuWE3N7K2kOzdu1fJZFJlZWWdri8rK1NjY2OX92lsbOzR9h5SqZRmzpyp8ePHa8yYMd1ud8455+ipp57SSy+9pKefflqpVEpXXHGFPv74415c7dFqamq0ZMkSrVixQgsXLtSOHTv0la98Rfv37+9y+75wTg5bvny59u3bp+9+97vdbpOt5+VIhx/fnjz2J/OayzbMjex9foZ1djA37OZG1n3ab9jV1dXp3XffPebPTiVp3LhxGjduXPrrK664Queee66eeOIJ3XfffZleZrcmTpyY/u8LLrhANTU1GjFihF588UXdfPPNbuuy8Otf/1oTJ05UZWVlt9tk63lBuPX1uSGFd3YwN+xk7TskQ4cOVTQa1e7duztdv3v3bpWXl3d5n/Ly8h5t39tmzJihl19+Wa+++mqPPiZdkvLy8nTRRRdp+/btGVrdyRk4cKDOPvvsbteV7efksJ07d+pPf/qTvve97/Xoftl6Xg4/vj157E/mNZdtmBudZevzUwrH7GBu2M6NrC0k+fn5uuSSS7Rq1ar0dalUSqtWrerUNL9o3LhxnbaXpJUrV3a7fW8JgkAzZszQsmXL9Oc//1nV1dU9zkgmk9qyZYsqKioysMKTd+DAAX344Yfdritbz8mRFi9erGHDhmnSpEk9ul+2npfq6mqVl5d3euybm5u1fv36bh/7k3nNZRvmRmfZ+vyUwjE7mBvGc6NHvwLby55//vkgFosFS5YsCf72t78Ft956azBw4MCgsbExCIIg+M53vhPcfffd6e3feOONIDc3N3jkkUeC999/P5g3b16Ql5cXbNmyxesQgiAIgttvvz2Ix+PB6tWrg08//TR9OXjwYHqbI4/lnnvuCV555ZXgww8/DDZu3BjceOONQUFBQfDee+95HELaj370o2D16tXBjh07gjfeeCOora0Nhg4dGuzZsycIgr5zTr4omUwGw4cPD+66666jbsvm87J///5g8+bNwebNmwNJwaOPPhps3rw52LlzZxAEQfDggw8GAwcODF566aXgr3/9azB58uSguro6OHToUDrj61//evD444+nvz7ea64vYG5kx/PzSGGbHcwN+7mR1YUkCILg8ccfD4YPHx7k5+cHl19+ebBu3br0bV/72teCadOmddr+xRdfDM4+++wgPz8/GD16dPD73/++l1d8NEldXhYvXpze5shjmTlzZvq4y8rKgm984xvBpk2ben/xR7jhhhuCioqKID8/P/jSl74U3HDDDcH27dvTt/eVc/JFr7zySiAp2Lp161G3ZfN5efXVV7t8Xh1ebyqVCubMmROUlZUFsVgsuPrqq486xhEjRgTz5s3rdN2xXnN9BXPD//l5pLDNDubGvE7XWcyNSBAEQc/eUwEAALCVtb9DAgAA+g8KCQAAcEchAQAA7igkAADAHYUEAAC4o5AAAAB3FBIAAOCOQgIAANxRSAAAgDsKCQAAcEchAQAA7igkAADA3f8F/7udU0cEKtQAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.subplot(121)\n",
    "plt.imshow(activation['k1'][0][0], aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(activation['w1'][0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.subplot(121)\n",
    "plt.imshow(activation['k2'][0][0], aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(activation['w2'][0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.subplot(121)\n",
    "plt.imshow(activation['k3'][0][0], aspect='auto')\n",
    "plt.subplot(122)\n",
    "plt.imshow(activation['w3'][0][0], aspect='auto')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "9b3b15e79d64212a14c381e1bc9a41101994b32312634469deb1a16fd6054240"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
